#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m;
vector<int> adj[N];
vector<int> vec[N];
int indeg[N];
// 考虑前x条信息时的图
void build(int x) {
  for (int i = 0; i <= n; ++i) adj[i].clear();
  memset(indeg, 0, sizeof indeg);
  for (int i = 1; i <= x; ++i) {
    for (int j = 0; j < vec[i].size() - 1; ++j) {
      int u = vec[i][j], v = vec[i][j + 1];
      adj[u].push_back(v);
      indeg[v]++;
    }
  }
}

bool check(int x) {
  build(x);
  // 不要用priority_queue，会多一个log
  queue<int> q;
  int cnt = 0;
  for (int i = 1; i <= n; ++i)
    if (!indeg[i]) q.push(i);
  while (q.size()) {
    int u = q.front();
    q.pop();
    cnt++;
    for (int v : adj[u]) {
      indeg[v]--;
      if (!indeg[v]) q.push(v);
    }
  }
  return cnt == n;
}

void get_ans(int x) {
  build(x);
  // 小根堆以保证输出字典序
  priority_queue<int, vector<int>, greater<int>> q;
  for (int i = 1; i <= n; ++i)
    if (!indeg[i]) q.push(i);
  while (q.size()) {
    int u = q.top();
    q.pop();
    cout << u << ' ';
    for (int v : adj[u]) {
      indeg[v]--;
      if (!indeg[v]) q.push(v);
    }
  }
  cout << endl;
}

int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int si;
    cin >> si;
    for (int j = 1; j <= si; ++j) {
      int x;
      cin >> x;
      vec[i].push_back(x);
    }
  }
  int l = 1, r = m, ans;
  while (l <= r) {
    int mid = (l + r) / 2;
    if (check(mid))
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  get_ans(ans);
}
